﻿using GalaSoft.MvvmLight;
using PropertyChanged;
using sys_Print.DataAsset;
using sys_Print.Models;
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows;
using GalaSoft.MvvmLight.Command;
using System.Windows.Media;
using System.Windows.Input;
using System.Collections.ObjectModel;

namespace sys_Print.ViewModel
{
    [AddINotifyPropertyChangedInterface]
    public class DemoViewModel : ViewModelBase
    {
        [DoNotNotify]
        private readonly IFreeSql _fsql;
        [DoNotNotify]
        private PrintDialog printDialog = new PrintDialog();
        public PrintModel PrintModel { get; set; } = new PrintModel();
        public List<PrintModelType> PrintModelTypes { get; set; } = new List<PrintModelType>();
        public List<PrintCanvasModel> PrintCanvasModels { get; set; }
        public RelayCommand DropDownOpenedCommand { get; private set; }
        public RelayCommand DropDownClosedCommand { get; private set; }
        public RelayCommand PrinterDropDownClosedCommand { get; private set; }
        public RelayCommand<TextBox> EnterKeyPressedSearchBar { get; private set; }
        public RelayCommand<DataGridRow> DataGridRowDeleteCommand { get; private set; }
        public RelayCommand<Meter> ListViewItemClickCommand { get; private set; }
        public RelayCommand AddDataGridButtonCommand { get; private set; }
        public RelayCommand PrintButtonCommand { get; private set; }
        public RelayCommand AllPrintButtonCommand { get; private set; }

        public DemoViewModel() 
        {
            // 获取配置好的FreeSql实例
            _fsql = App.FsqlDB;

            //模板选择事件
            DropDownOpenedCommand = new RelayCommand(new Action(CommandDropDownOpened));
            DropDownClosedCommand = new RelayCommand(new Action(CommandDropDownClosed));

            PrinterDropDownClosedCommand = new RelayCommand(new Action(CommandPrinterDropDownClosed));

            EnterKeyPressedSearchBar = new RelayCommand<TextBox>(new Action<TextBox>(SearchBarEnterKeyPressed));
            DataGridRowDeleteCommand = new RelayCommand<DataGridRow>(new Action<DataGridRow>(CommandDataGridRowDelete));

            ListViewItemClickCommand = new RelayCommand<Meter>(new Action<Meter>(CommandListViewItemClick));

            AddDataGridButtonCommand = new RelayCommand(new Action(AddDataGridButton));
            PrintButtonCommand = new RelayCommand(new Action(OnPrintButton));
            AllPrintButtonCommand = new RelayCommand(new Action(OnAllPrintButton));
        }

        /// <summary>
        /// 选中打印机
        /// </summary>
        private void CommandPrinterDropDownClosed()
        {
            printDialog.PrintQueue = PrintModel.selectedPrinter;
        }

        /// <summary>
        /// 全部打印
        /// </summary>
        private void OnAllPrintButton()
        {
            if (PrintModel.Unprinteds == null || PrintModel.Unprinteds.Count == 0)
            {
                HandyControl.Controls.Growl.Warning("没有打印数据！");
                return;
            }

            // 获取要打印的 Canvas
            Canvas printCanvas = FindVisualChild<Canvas>(App.Current.MainWindow, "PrintCanvas");

            for (int i = 0; i < PrintModel.Unprinteds.Count; i++)
            {
                //加载标定参数
                CommandListViewItemClick(PrintModel.Unprinteds[i]);

                //手动刷新 Canvas UI
                printCanvas.InvalidateVisual();

                try
                {
                    // 打印 Canvas 中的内容
                    printDialog.PrintVisual(printCanvas, PrintModel.Unprinteds[i].FactoryBarcode);
                }
                catch (Exception ex)
                {
                    // 处理异常，或者记录异常信息
                    MessageBox.Show("打印时出现错误: " + ex.Message);
                }
            }
        }

        /// <summary>
        /// 新增项目行
        /// </summary>
        private void AddDataGridButton()
        {
            if(PrintModel.DataGridLists != null)
            {
                PrintModel.DataGridLists.Add(new DataGridList() { AttributeName = "项目名称",ContentName= "项目内容" });
            }
                        
            PrintModel.RowHeightCalculator(PrintCanvasModels);
        }

        //调试加载标定参数，示值误差、重复性、仪表系数、标定介质、检定温度、大气压力、相对湿度
        /// <summary>
        /// 单击列表加载标定参数
        /// </summary>
        /// <param name="meter">标定信息对象</param>
        private void CommandListViewItemClick(Meter meter)
        {
            //映射打印模板标定参数
            meter.ModelObjectHandler(PrintCanvasModels);

            //映射内容模板标定参数
            meter.ModelObjectToListHandler(PrintModel.ContentEntries);

            //填充内容数据
            ObservableCollection<DataGridList> dataGridLists = new ObservableCollection<DataGridList>();

            foreach (ContentEntries item in PrintModel.ContentEntries)
            {
                // 将单位中的 "3" 替换为 "³"
                string unit = item.Unit?.Replace("3", "³");

                // Qₜ - Qₘᵢₙ

                dataGridLists.Add(new DataGridList() { AttributeName = $"{item.Prefix}{item.AttributeName}{item.Suffix}{unit}", ContentName = item.ContentName });
            }

            PrintModel.DataGridLists = dataGridLists;   
        }

        /// <summary>
        /// 从数据集合中删除该数据项
        /// </summary>
        /// <param name="row"></param>
        private void CommandDataGridRowDelete(DataGridRow row)
        {
            if (row != null && row.DataContext is DataGridList dataItem)
            {
                PrintModel.DataGridLists.Remove(dataItem);
            }

            PrintModel.RowHeightCalculator(PrintCanvasModels);
        }

        /// <summary>
        /// 加载单据模板
        /// </summary>
        private void CommandDropDownClosed()
        {
            if(PrintModel.SelectedPrintModelType == null)
            {
                HandyControl.Controls.Growl.Warning("请选择模板！");
                return;
            }
            PrintCanvasModels = new List<PrintCanvasModel>();

            PrintCanvasModels = _fsql.Select<PrintCanvasModel>()
            .Where(a => a.ModelId == PrintModel.SelectedPrintModelType.Id)
            .OrderBy(a => a.OrderNo)
            .ToList();

        }

        //选择单据类型时，根据打印机名称自动选择打印，如果找不到打印机，则提示
        /// <summary>
        /// 下拉框显示单据类型
        /// </summary>
        private void CommandDropDownOpened()
        {
            PrintCanvasModels = new List<PrintCanvasModel>();

            PrintModelTypes = _fsql.Select<PrintModelType>().ToList();

            //加载默认打印机，并修改下拉框选择项
        }

        /// <summary>
        /// 任务单输入框键盘按下事件
        /// </summary>
        private void SearchBarEnterKeyPressed(TextBox textBox)
        {
            // 处理按下回车键的逻辑，参数text为TextBox中的文本内容
            if (Keyboard.IsKeyDown(Key.Return))
            {
                //格式化任务单号
                FBillNoFormat(textBox.Text);
            }
        }

        /// <summary>
        /// 输入任务单加载任务参数
        /// 1、确认选择模板
        /// 2、格式任务单号
        /// 3、判断数据源
        /// 4、读取任务信息，映射打印模板任务参数
        /// 5、判断标定信息
        /// 6、判断是否显示追溯码
        /// 7、判断内容模板
        /// 8、映射内容模板任务参数
        /// </summary>
        /// <param name="text"></param>
        private void FBillNoFormat(string text)
        {
            if(PrintModel.SelectedPrintModelType == null)
            {
                HandyControl.Controls.Growl.Warning("请选择模板！");                
                return;
            }
            //任务单号格式化
            if (!(text ?? "WORK").StartsWith("WORK"))
            {
                text = text.Length >= 6 ? text.Substring(text.Length - 6) : text.PadLeft(6, '0');
                PrintModel.Tisk = "WORK" + text;
            }
            else
            {
                PrintModel.Tisk = text;
            }

            //判断数据源
            String source = "Meter";
            if (PrintModel.DataSource == false)
            {
                source = "MeterTan";
            }

            //获取任务单关联信息
            PrintModel.TaskInfo = _fsql.Select<TaskInfo>()
                                .Where(a => a.FBillNo == PrintModel.Tisk)
                                .ToOne();

            if (PrintModel.TaskInfo == null)
            {
                HandyControl.Controls.Growl.Warning("请确认任务单号！");
                return;
            }

            //根据办事处修改Logo图片名称
            PrintModel.LogoName = _fsql.Ado.QuerySingle<string>("SELECT FShortName FROM ais20160331162100.dbo.t_organization  WHERE FName = @FName", new { FName = PrintModel.TaskInfo.Customer }); ;

            //任务单关联信息加载
            PrintModel.TaskInfo.ModelObjectHandler(PrintCanvasModels);

            //获取未打印出厂编号
            PrintModel.Unprinteds = _fsql.Ado.Query<Meter>("SELECT * FROM " + source + " WHERE TaskNumber = @TaskNumber ", new { TaskNumber = PrintModel.Tisk });
            
            if (PrintModel.Unprinteds == null)
            {
                HandyControl.Controls.Growl.Info("此任务单无标定数据！");
                return;
            }

            //判断此任务单是否显示追溯码
            if (PrintModel.Unprinteds[0].ENNTraceCode == null)
            {
                foreach (PrintCanvasModel item in PrintCanvasModels)
                {
                    if(item.ControlType == "ENNQRCode")
                    {
                        item.IsdisplayKeyword = false;
                    }
                }
            }
            else
            {
                foreach (PrintCanvasModel item in PrintCanvasModels)
                {
                    if (item.ControlType == "ENNQRCode")
                    {
                        item.IsdisplayKeyword = true;
                    }
                }
            }

            //加载内容模板:根据办事处与产品系列判断
            PrintModel.ContentType = _fsql.Select<ContentType>()
                                    .Where(a => a.CustomerName == PrintModel.TaskInfo.Customer && a.ProductFamilyNo == PrintModel.TaskInfo.FNumber.Substring(3, 2))
                                    .ToOne();

            //如果找不到模板
            if (PrintModel.ContentType == null)
            {
                //加载内容模板:根据产品系列判断
                PrintModel.ContentType = _fsql.Select<ContentType>()
                                        .Where(a => a.ProductFamilyNo == PrintModel.TaskInfo.FNumber.Substring(3, 2))
                                        .ToOne();

                //如果找不到模板
                if (PrintModel.ContentType == null)
                {
                    //加载默认内容模板
                    PrintModel.ContentType = _fsql.Select<ContentType>()
                                            .Where(a => a.ContentModelId == 1)
                                            .ToOne();
                }

            }

            //加载内容模板数据
            PrintModel.ContentEntries = _fsql.Select<ContentEntries>()
                                            .Where(a=> a.ContentModelId == PrintModel.ContentType.ContentModelId)
                                            .ToList();

            PrintModel.TaskInfo.ModelObjectToListHandler(PrintModel.ContentEntries);
            
            //自动加载第一条查询的标定数据
            CommandListViewItemClick(PrintModel.Unprinteds[0]);

            HandyControl.Controls.Growl.Info("查询完成！");
        }

        /// <summary>
        /// 打印
        /// </summary>
        private void OnPrintButton()
        {
            if (PrintModel.Unprinteds == null || PrintModel.Unprinteds.Count == 0)
            {
                HandyControl.Controls.Growl.Warning("没有打印数据！");
                return;
            }
            // 获取要打印的 Canvas
            Canvas printCanvas = FindVisualChild<Canvas>(App.Current.MainWindow, "PrintCanvas");
            try
            {
                // 打印 StackPanel 中的内容
                printDialog.PrintVisual(printCanvas, "Printing Canvas");
            }
            catch (Exception ex)
            {
                // 处理异常，或者记录异常信息
                MessageBox.Show("打印时出现错误: " + ex.Message);
            }
        }

        /// <summary>
        /// Helper方法：在视觉树中查找指定名称的元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent">视觉树对象</param>
        /// <param name="name">元素名称</param>
        /// <returns>元素对象</returns>
        private static T FindVisualChild<T>(DependencyObject parent, string name) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child is T element && (element as FrameworkElement)?.Name == name)
                {
                    return element;
                }

                T result = FindVisualChild<T>(child, name);

                if (result != null)
                {
                    return result;
                }
            }

            return null;
        }

    }
}
